package com.sale.plugins;

import com.apache.api.manager.ProxyManager;
import com.apache.api.vo.ParamsVo;
import com.apache.api.vo.ResultEntity;
import com.apache.cache.util.Validator;
import com.apache.database.constant.SpringContextLoader;
import com.apache.exception.BusinessException;
import com.apache.ius.plugin.CustomMethodPlugin;
import com.apache.ius.plugin.UtilPlugin;
import com.apache.tools.DataMap;
import com.apache.tools.NumberUtils;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 发售交易-申购抽签摇号：
 * 随机摇号
 *
 * @author admin
 */
public class SaleYaoHaoPluginImpl implements CustomMethodPlugin {

    private Logger log = Logger.getLogger(getClass());

    @Override
    public Object beforeInvoke(Map<String, Object> param) {
        log.info("start->> 【发售交易】摇号开始");
        log.info("start->> 接收参数：" + param);
        //获取参数（活动ID）
        String saleId = String.valueOf(param.get("trsSale.w_saleId"));
        if (Validator.isNull(saleId)) {
            throw new BusinessException("saleId参数缺失！");
        }
        //查询发行活动对象,获取发行总数，发行最小变动量，发行实际申购总数量===========
        DataMap saleMap = getSaleInfo(param, saleId);
        if (saleMap == null || saleMap.size() < 1) {
            throw new BusinessException("未找到发行活动");
        }
        //获取活动相关参数。
        String saleNum = String.valueOf(saleMap.get("saleNum"));//此活动的发行总数量
        String buyTotalNum = String.valueOf(saleMap.get("buyTotalNum"));
        ;//此活动实际申购总数量
        String minChangeNum = String.valueOf(saleMap.get("minChangeNum"));
        ;//此活动规则：最小变动单位

        double totalSale = NumberUtils.getDouble(saleNum, 0,true);
        double totalPurchaseNum = NumberUtils.getDouble(buyTotalNum, 0,true);//申购数量总和
        double minPurchaseNum = NumberUtils.getDouble(minChangeNum, 0,true);//最小申购变动量
        //计算发行总数(总发行量/最小变动单位)
        long totalSaleNum = Math.round(NumberUtils.divide(totalSale, minPurchaseNum, 2));
        //计算出本次最大配号数（申购总数量/最小变动单位）
        long totalAllocationNumber = Math
                .round(NumberUtils.divide(totalPurchaseNum, minPurchaseNum, 2));
        log.info("本次中签号码个数：" + totalAllocationNumber);

        //暂存中签号Map
        Map<String, String> map = new HashMap<String, String>();
        /**
         * 循环获取中签号码（循环次数不定）while循环,当达到申购总数，或者达到总发行数结束i
         * 1.通过Math.random()随机数获取中签号码randomNumber
         * 2.拼接中签号尾号
         * 3.判断中签尾号是否存在于Map中，没有则继续，有则进行下一次循环
         *  	将当前中签号码存入Map中
         *  	查询数据，将本条数据改为中签数据
         *  		sql：update trs_numbers set is_select='T' where sale_id='' and rand_number like'%randomNumber';
         *  	i++
         *
         */
        int i = 0;
        String endAllocationNumber = "";
        int maxTotalAllocationLen = (totalAllocationNumber + "").length();
        int selectCount = 0;
        while (i < totalAllocationNumber && selectCount < totalSale) {
            //配号从0开始（随机1-最大中签数）
            int round = (int) Math.floor(Math.random() * totalAllocationNumber);

            //新生成尾号
            String newStr = round + "";
            //新生成尾号长度
            int newNumLength = newStr.length();
            //新生成尾号长度等于最大配号长度，新生成尾号不补位
            if (newNumLength == maxTotalAllocationLen) {
                endAllocationNumber = newStr;
            } else {
                //新生成浩长度小于最大配号长度，新生成配号补位
                while (newNumLength < maxTotalAllocationLen) {
                    newStr = "0" + newStr;
                    newNumLength++;
                }
                endAllocationNumber = newStr;
            }
            if (null != map.get(endAllocationNumber)) {
                continue;
            } else {
                map.put(endAllocationNumber, endAllocationNumber);
                //查询当前配号尾号配号信息
                DataMap numberUserInfo = getNumberUserInfo(endAllocationNumber, saleId);
                String numberId = String.valueOf(numberUserInfo.get("numberId"));
                //修改当前中签尾号配号信息is_select='T';
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("trsNumbers.isSelect", "T");
                params.put("trsNumbers.remark", "此号已中签，等待扣款");
                params.put("trsNumbers.w_numberId", numberId);
                params.put("trsNumbers.w_saleId", saleId);
                log.info("摇号池内saleId=" + saleId + "的中签尾号【" + endAllocationNumber + "】标记【中签】");
                updateNumberInfo(params);
                selectCount += Integer.parseInt((String) numberUserInfo.get("nums"));
                i++;
            }
        }
        //将所有未中签配号remark标记为已“摇号结束，未中签”
        Map<String, Object> notSelectParams = new HashMap<String, Object>();
        notSelectParams.put("trsNumbers.w_isSelect", "F");
        notSelectParams.put("trsNumbers.remark", "摇号结束，未中签");
        notSelectParams.put("trsNumbers.w_saleId", saleId);
        log.info("摇号池内saleId=" + saleId + "的配号，未中签的标记【摇号结束，未中签】");
        updateNumberInfo(notSelectParams);
        //将所有申购表数据状态改为30，（摇号结束）
        Map<String, Object> saleBuyParams = new HashMap<String, Object>();
        saleBuyParams.put("trsBuy.w_saleId", saleId);
        saleBuyParams.put("trsBuy.buyStatus", "30");
        updateBuyInfo(saleBuyParams);
        return null;
    }

    /**
     * 修改配好表信息，更新中签状态
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object updateNumberInfo(Map<String, Object> numbersMap) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
//        params.setParams(numbersMap);
//        params.setParams("doCode", "dymicSql");
//        params.setParams("sqlKeyId", "ByDymicSql");
//        params.setParams("resultType", "processSql");
//        params.setKey("iusTransaction");
        //封装参数
//        params.setParams("modelTypes", "u_trsNumbers");
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);
//        Map result = (Map) dymicSqlParamResult.getEntity();


        ResultEntity dymicSqlParamResult = UtilPlugin.getInstance().saveByParams("sale","u_trsNumbers",numbersMap);


        return null;
    }

    /**
     * 修改配好表信息，更新申购表
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object updateBuyInfo(Map<String, Object> buyParams) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
//        params.setParams(buyParams);
//        params.setParams("doCode", "dymicSql");
//        params.setParams("sqlKeyId", "ByDymicSql");
//        params.setParams("resultType", "processSql");
//        params.setKey("iusTransaction");
        //封装参数
//        params.setParams("modelTypes", "u_trsBuy");
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);

        ResultEntity dymicSqlParamResult = UtilPlugin.getInstance().saveByParams("sale","u_trsBuy",buyParams);

        Map result = (Map) dymicSqlParamResult.getEntity();
        return null;
    }

    /**
     * 【目前未使用】获取当前中签尾号的配号表信息，userId,randNumber,count(isSelect)
     *
     * @param endAllocationNumber
     * @return
     */
    @SuppressWarnings("rawtypes")
    public DataMap getUserId(String endAllocationNumber) {
        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
                .getBean("netProxyManager");
        ParamsVo params = new ParamsVo();
        params.setParams("sqlKeyId", "ByObjInfo");
        params.setKey("publicForSql");
        StringBuffer dyncSql = new StringBuffer("select t.rand_number,t.user_id,");
        dyncSql.append(" (select count(*) from trs_numbers tn where tn.is_select='T') is_select ");
        dyncSql.append("from trs_numbers t,");
        dyncSql.append("(select t2.user_id from trs_numbers t2 where t2.rand_number like '%"
                + endAllocationNumber + "') t3");
        dyncSql.append(" where t.user_id=t3.user_id");
        params.setParams("dyncSql", dyncSql.toString());
        System.out.println("摇号SQL=>" + dyncSql);
        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);
        List<DataMap> list = (List) dymicSqlParamResult.getEntity();
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 综合查询：申购活动sale对象、申购总量、申购用户数、最小变动单位等
     *
     * @param param
     * @param saleId
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public DataMap getSaleInfo(Map<String, Object> param, String saleId) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
        String rulesNo = "sale01";//申购最小变动单位规则rulesNo
//        params.setParams("sqlKeyId", "ByObjInfo");
//        params.setKey("publicForSql");
        StringBuffer dyncSql = new StringBuffer("select s.*,");
        dyncSql.append("(select p.param_no from trs_rules_pro p where p.sale_id='" + saleId
                + "' and p.rules_no='" + rulesNo + "') as min_change_num ,");
        dyncSql.append("(select sum(t.num) from trs_buy t where t.sale_id='" + saleId
                + "')  as buy_total_num,");//申购总数量
        dyncSql.append("(select count(*) from trs_buy t where t.sale_id='" + saleId
                + "')  as buy_user_count ");//申购总人数
        dyncSql.append(" from trs_sale s where  s.sale_id='" + saleId + "'");
//        params.setParams("dyncSql", dyncSql.toString());
        System.out.println("摇号-查询发行活动SQL=>" + dyncSql);
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);


        List<DataMap> list = (List<DataMap>)UtilPlugin.getInstance().selectObjectForDatasource(dyncSql.toString(),"sale");

//        List<DataMap> list = (List) dymicSqlParamResult.getEntity();
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 查询所有交易商的申购列表
     *
     * @param param
     * @param saleId
     * @return
     */
    @SuppressWarnings("rawtypes")
    public List<DataMap> getBuyListData(Map<String, Object> param, String saleId) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
//        params.setParams("doCode", "dymicSql");
//        params.setParams("sqlKeyId", "ByDymicSql");
//        params.setParams("resultType", "objInfo");
//        params.setKey("publicForSql");
//
//        //封装参数
//        params.setParams("modelTypes", "s_trsBuy");
//        params.setParams("trsBuy.w_saleId", saleId);
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);

        Map<String, Object> whereMap =  new HashMap<String,Object>();
        whereMap.put("trsSale.w_saleId", saleId);
        List<DataMap> list  = UtilPlugin.getInstance().getListByParams("sale","s_trsBuy",whereMap);
//        List<DataMap> list = (List) dymicSqlParamResult.getEntity();
        return list;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public DataMap getNumberUserInfo(String endAllocationNumber, String saleId) {
//        ProxyManager netProxyManager = (ProxyManager) SpringContextLoader
//                .getBean("netProxyManager");
//        ParamsVo params = new ParamsVo();
//        params.setParams("sqlKeyId", "ByObjInfo");
//        params.setKey("publicForSql");
        StringBuffer dyncSql = new StringBuffer(
                "select tn.* from trs_numbers tn where tn.sale_id='" + saleId
                        + "' and tn.rand_number like '%" + endAllocationNumber + "'");
//        params.setParams("dyncSql", dyncSql.toString());
        System.out.println("摇号查询发行SQL=>" + dyncSql);
//        ResultEntity dymicSqlParamResult = (ResultEntity) netProxyManager.doInvoke(params);
//        List<DataMap> list = (List) dymicSqlParamResult.getEntity();
        List<DataMap> list = (List<DataMap>)UtilPlugin.getInstance().selectObjectForDatasource(dyncSql.toString(),"sale");

        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Object doInvoke(Map<String, Object> param) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Object afterInvoke(Map<String, Object> param) {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * 规则校验入口（专门给系统公式规则提供的）
     *
     * @param paramsVo
     */
    public void run(ParamsVo paramsVo) {
        beforeInvoke(paramsVo.getParams());
    }

    public static void main(String[] args) {
        //总有效申购数
        int totalPurchaseNum = 20;
        //最低申购数
        int minPurchaseNum = 2;
        //最大配号数
        int totalAllocationNumber = totalPurchaseNum / minPurchaseNum;
        System.out.println("最大配号数：" + totalAllocationNumber);
        //本次發行量
        int saleNum = 10;
        //本次中簽率
        double pre = (double) saleNum / totalPurchaseNum;
        //本次中簽數
        int zqNumber = (int) (totalAllocationNumber * pre);
        System.out.println("中签数：" + zqNumber);
        //获取申购数据
        //TODO 查询数据
        /**
         * 获取申购表数据，通过发售活动ID（saleId)。
         */
//        List<TrsNumbers> list = new ArrayList<TrsNumbers>();
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        int i = 0;
        while (i < zqNumber) {
            int round = (int) Math.round(Math.random() * totalAllocationNumber);
            System.out.println(i + "======" + round);
            if (map.get(round) == null) {
                int length = (round + "").length();
                int length2 = (totalAllocationNumber + "").length();
                String newStr = round + "";
                while (length < length2) {
                    if (length < length2) {
                        newStr = "0" + round;
                    }
                    length++;
                }
                //TODO
                /**
                 * 判断trs_number 表中拥有该号的申购者是否已有中标申购号。
                 * select * from trs_number where rand_number like '%newStr' and is_select = 'T'
                 * 如果有
                 * 	continue;
                 * 如果没有，将本条数据设为中标is_select=T
                 * 修改本条数据
                 * 	i++;
                 *
                 * 达到中签总数结束
                 */
                map.put(round, round);
                System.out.println(i + "*****" + newStr);
                i++;
            } else {
                continue;
            }
        }
    }

}
